#ifndef __HomeTether_pulses_H__
#define __HomeTether_pulses_H__

#include "common.h"

// ======================================================================
// About pulse receiving and parsing
// ======================================================================
#ifndef PULSE_CapturedData_Timeout
#  define PULSE_CapturedData_Timeout  (2000) // 2sec
#  define PULSE_1_PL_MAX_DUR_MSEC     (50)	 // 50msec
#endif // PULSE_CapturedData_Timeout

typedef uint8_t (*ReadPin_f) (void);

bool Pulses_capture(uint16_t* captureBuf, uint8_t captureBufLen, uint16_t usecSampleIntv, ReadPin_f readPin);

typedef struct _PulseSeq
{
	uint16_t short_durXusec;
	uint8_t seqlen;
	uint8_t* seq;
} PulseSeq;

typedef struct _PendingPulseSeq
{
	PulseSeq ps;
	uint16_t  timeout;
} PendingPulseSeq;

//@param[in]  captureBuf the buf prepared by Pulses_capture() that keeps the pulses counted in sample usec: hi->low->hi->low->... and termimated with a 0xffff
//@param[in]  usecSampleIntv sample interval in usec, same as when call Pulses_capture()
//@param[out] out the compressed result: out->seq[0+] top 4bits of each byte is the hi sig multiplier based on short_dur, 
//                                       low 4bits the low sig multipler. if the multipler is greater than 0x8, the pair of
//                                       plus will expand to two bytes leading by a 0x80 flag
bool PulseSeq_compress(uint16_t* captureBuf, uint16_t usecSampleIntv, PulseSeq* out);

// ======================================================================
// About pulse codec
// ======================================================================
typedef struct _PulseCode
{
	uint8_t  profId;
	uint16_t short_durXusec;
	uint32_t code;
} PulseCode;

typedef enum _PulseProfId_e
{
	PulseProfId_PT2262_EV1527 =0,
	PulseProfId_uPD6121,
	PulseProfId_TC9012F,
	PulseProfId_M7461M,

	PulseProfId_UNKNOWN,
	PulseProfId_MAX = PulseProfId_UNKNOWN
} PulseProfId_e;

uint8_t	Pulse_findProfId(const char* profname);
const char*	Pulse_profName(uint8_t profId);

bool Pulses_encode(PulseSeq* out, const uint32_t code, uint8_t profileId, uint16_t short_durXusec, uint8_t isRepeat);
bool Pulses_encodeEx(const PulseCode* in, PulseSeq* out, uint8_t isRepeat);

bool Pulses_decode(const PulseSeq* in, uint32_t* pCode, uint8_t* pProfId, uint16_t* pShort_durXusec);
bool Pulses_decodeEx(const PulseSeq* in, PulseCode* out);

// ======================================================================
// About pulse sending
// ======================================================================
typedef void (*SetPulsePin_f) (uint8_t high);
uint8_t PulseSeq_send(PulseSeq* in, SetPulsePin_f sender);
bool    PulseCode_send(PulseCode* code, SetPulsePin_f sender, uint8_t repeatTimes);


#ifdef __CC_ARM	
// ======================================================================
// About pulse sending
// ======================================================================
void PulseSend_bySeq(const IO_PIN* pin, bool HeqH, PulseSeq* in);
void PulseSend_byProfileId(uint8_t profileId, uint32_t code, const IO_PIN* pin, uint8_t HeqH, uint32_t baseIntvXusec);
void PulseSend_byProfile(char* profileName, uint32_t code, const IO_PIN* pin, uint8_t HeqH, uint32_t baseIntvXusec);
#endif // __CC_ARM

#endif // __HomeTether_pulses_H__
